package org.acme.oauth2.restasured;


import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import java.security.Principal;

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.StreamingOutput;
import java.util.HashMap;
import java.util.Map;

/**
 * @author LiJian
 * @date 2021/6/8 10:59
 */
@Path("/sec")
public class RestAssuredResource {
    @GET
    @Path("permit-all")
    @Produces(MediaType.TEXT_PLAIN)
    @PermitAll
    public String hello(@Context SecurityContext ctx) {
        Principal caller = ctx.getUserPrincipal();
        String name = caller == null ? "anonymous" : caller.getName();
        String helloReply = String.format("hello + %s, isSecure: %s, authScheme: %s", name, ctx.isSecure(),
                ctx.getAuthenticationScheme());
        return helloReply;
    }
    @GET()
    @Path("roles-allowed")
    @RolesAllowed({ "READER", "WRITER" })
    @Produces(MediaType.TEXT_PLAIN)
    public String helloRolesAllowed(@Context SecurityContext ctx) {
        Principal caller = ctx.getUserPrincipal();
        String name = caller == null ? "anonymous" : caller.getName();
        String helloReply = String.format("hello + %s, isSecure: %s, authScheme: %s", name, ctx.isSecure(),
                ctx.getAuthenticationScheme());
        return helloReply;
    }
    /**
     * 授权码方式实现
     * @return
     */
    @GET()
    @Path("login")
    @Produces(MediaType.TEXT_PLAIN)
    public String getOAuth2ServiceResources()
    {
        final String accessToken = getAccessToken("tdfuivue", "admin", "123456");

        final Response fooResponse = RestAssured.given().header("Authorization", "Bearer " + accessToken).get("http://localhost:8080/user/me");

        return  accessToken;
    }

    public String getAccessToken(String clientId, String username, String password ){

        final String redirectUrl = "http://localhost:8080/code";
        final String authorizeUrl = "http://192.168.99.77:9998/oauth/authorize?response_type=code&response_type=code&client_id=" + clientId + "&redirect_uri=" + redirectUrl;
        final String tokenUrl = "http://192.168.99.77:9998/oauth/token";
        // 用户登录
        Response response = RestAssured.given().get(authorizeUrl);
        final String xsrfCookieValue=response.getCookie("XSRF-TOKEN");
        System.out.println(xsrfCookieValue);

        response = RestAssured.given()
                .formParams("username", username
                        , "password", password
                        , "_csrf", xsrfCookieValue)
                .post("http://localhost/login");
        final String cookieValue = response.getCookie("JSESSIONID");

        //授权服务器返回Code
        Map<String, String> params = new HashMap<String, String>();
        params.put("user_oauth_approval", "true");
        params.put("authorize", "Authorize");
        params.put("scope.app", "true");
        params.put("scope.foo", "true");
        response = RestAssured
                .given()
                .cookie("JSESSIONID", cookieValue)
                .formParams(params)
                .post(authorizeUrl);

        final String location = response.getHeader("code");
        final String code = location.substring(location.indexOf("code=") + 5);

        //携带Code请求授权服务器，获取token
        params = new HashMap<String, String>();
        params.put("grant_type", "authorization_code");
        params.put("code", code);
        params.put("client_id", clientId);
        params.put("redirect_uri", redirectUrl);
        response = RestAssured.given().auth().basic(clientId, "secret").formParams(params).post(tokenUrl);
        return response.jsonPath().getString("access_token");
    }
    /**
     * 密码方式实现
     * @return
     */
    @GET
    @Path("password")
    @Produces(MediaType.APPLICATION_JSON)
    public String getOAuth2PasswordClient()
    {
        final String tokenUrl = "http://192.168.99.77:9998/oauth/token";
        final String getTokenUrl="http://192.168.99.77:9998/oauth/token?client_id=tdfuivue&client_secret=tdfuivue&username=admin&password=123456&grant_type=password";
        final String userInfoUri = "http://192.168.99.77:9998/me";
        Map<String, String> params = new HashMap<String, String>();
        params.put("username", "admin");
        params.put("password", "123456");
        params.put("grant_type", "password");
        params.put("client_id", "tdfuivue");
        params.put("redirect_uri", "tdfuivue");
        Response response = RestAssured
                .given()
                .formParam("username","admin")
                .formParam("password","123456")
                .formParam("grant_type","password")
                .formParam("client_id","tdfuivue")
                .formParam("redirect_uri","tdfuivue")
                .when()
                .post(tokenUrl);
        System.out.println(response.getBody().print());
        response=RestAssured.given().post(getTokenUrl);
        //System.out.println(response.body().extract().path("access_token").get());
        return "获取成功："+response.body().print();
    }
    /**
     * 简化方式
     * @return
     */
    @GET
    @Path("implicit")
    @Produces(MediaType.APPLICATION_JSON)
    public String getOAuth2ImplicitClient()
    {
        final String tokenUrl = "http://192.168.99.77:9998/oauth/token";
        final String getTokenUrl="http://192.168.99.77:9998/oauth/token?client_id=tdfuivue&client_secret=tdfuivue&username=admin&password=123456&grant_type=password";
        Map<String, String> params = new HashMap<String, String>();
        params.put("username", "admin");
        params.put("password", "123456");
        params.put("grant_type", "password");
        params.put("client_id", "tdfuivue");
        params.put("redirect_uri", "tdfuivue");
        Response response = RestAssured
                .given()
                .formParams(params)
                .post(tokenUrl);
        response=RestAssured.given().post(getTokenUrl);

        return "获取成功："+response.body().print();
    }

    /**
     * 携带token获取用户认证
     * @param token
     * @return
     */
    @GET
    @Path("author/{token}")
    @Produces(MediaType.APPLICATION_JSON)
    public String getOauth2Authorization(@PathParam("token") String token){
        final String userInfoUri = "http://192.168.99.77:9998/me";
        Map<String, String> headers=new HashMap<String, String>();
        headers.put("Accept", "application/json");
        headers.put("Authorization", "Bearer "+token);
        Response response = RestAssured.given().headers(headers).post(userInfoUri);
        return "认证成功："+response.body().print();
    }
}
